﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SQLTouch.Service.DataContracts;

namespace SQLTouch.Client.Metro.ViewModel.Home
{
    public class HomeVM : VMBase
    {
        public class DatabaseVM : VMBase
        {
            private readonly DatabaseData model;

            public DatabaseVM(DatabaseData model)
            {
                this.model = model;
            }

            public DatabaseData Model
            {
                get { return model; }
            }

            public string ConnectionString
            {
                get { return model.ConnectionString; }
            }
        }

        private readonly IFacade facade;
        private readonly ObservableCollection<DatabaseVM> databases;
        private DatabaseVM selectedDatabase;
        private readonly RelayCommand editDatabase;
        private readonly RelayCommand addDatabase;
        private readonly RelayCommand deleteDatabase;
        private readonly RelayCommand explore;

        public HomeVM(IFacade facade)
        {
            this.facade = facade;
            this.databases = new ObservableCollection<DatabaseVM>(facade.GetDatabases().Select(p => new DatabaseVM(p)).ToList());

            facade.DatabaseAdded += database => databases.Add(new DatabaseVM(database));
            facade.DatabaseUpdated += database => databases.Replace(p => p.Model.Id == database.Id, new DatabaseVM(database));
            facade.DatabaseDeleted += database => databases.Remove(p => p.Model.Id == database.Id);

            this.editDatabase = new RelayCommand(DoEditDatabase, CanEditDatabase);
            this.addDatabase = new RelayCommand(DoAddDatabase);
            this.deleteDatabase = new RelayCommand(DoDeleteDatabase, CanDeleteDatabase);
            this.explore = new RelayCommand(DoExplore, CanExplore);
        }

        public ObservableCollection<DatabaseVM> Databases
        {
            get { return databases; }
        }

        public DatabaseVM SelectedDatabase
        {
            get { return selectedDatabase; }
            set
            {
                if (selectedDatabase != value)
                {
                    selectedDatabase = value;
                    RaisePropertyChanged("SelectedDatabase");
                    editDatabase.RaiseCanExecuteChanged();
                    deleteDatabase.RaiseCanExecuteChanged();
                    explore.RaiseCanExecuteChanged();
                }
            }
        }

        public RelayCommand EditDatabase
        {
            get { return editDatabase; }
        }

        public RelayCommand AddDatabase
        {
            get { return addDatabase; }
        }

        public RelayCommand DeleteDatabase
        {
            get { return deleteDatabase; }
        }

        public RelayCommand Explore
        {
            get { return explore; }
        } 

        private void DoEditDatabase()
        {
            facade.ShowEditDatabase(selectedDatabase.Model);
        }

        private bool CanEditDatabase()
        {
            return selectedDatabase != null;
        }

        private void DoDeleteDatabase()
        {
            facade.ShowDeleteDatabase(selectedDatabase.Model);
        }

        private void DoAddDatabase()
        {
            facade.ShowAddDatabase();
        }

        private bool CanDeleteDatabase()
        {
            return selectedDatabase != null;
        }

        private void DoExplore()
        {
            try
            {
                facade.GoToExplore(selectedDatabase.Model);
            }
            catch (Exception ex)
            {
                facade.ShowUnexpectedError("Unable to explore the database.", ex);
            }
        }

        private bool CanExplore()
        {
            return selectedDatabase != null;
        }
    }
}
